home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / PROGBLER / A86V318B.LZH / A06A.DOC < prev    next >
Text File  |  1988-01-14  |  17KB  |  345 lines

  1. CHAPTER 6    THE 86 INSTRUCTION SET
  2.  
  3.  
  4. Effective Addresses
  5.  
  6. Most memory data accessing in the 86 family is accomplished via
  7. the mechanism of the effective address.  Wherever an effective
  8. address specifier "eb", "ew" or "ed" appears in the list of 8086
  9. instructions, you may use a wide variety of actual operands in
  10. that instruction.  These include general registers, memory
  11. variables, and a variety of indexed memory quantities.
  12.  
  13. GENERAL REGISTERS: Wherever an "ew" appears, you can use any of
  14. the 16-bit registers AX,BX,CX,DX,SI,DI,SP, or BP.  Wherever an
  15. "eb" appears, you can use any of the 8-bit registers
  16. AL,BL,CL,DL,AH,BH,CH, or DH.  For example, the "ADD ew,rw" form
  17. subsumes the 16-bit register-to-register adds; for example, ADD
  18. AX,BX; ADD SI,BP; ADD SP,AX.
  19.  
  20. MEMORY VARIABLES: Wherever an "ew" appears, you can use a word
  21. memory variable.  Wherever an "eb" appears, you can use a byte
  22. memory variable.  Variables are typically declared in the DATA
  23. segment, using a DW declaration for a word variable, or a DB
  24. declaration for a byte variable.  For example, you can declare
  25. variables:
  26.  
  27.      DATA_PTR  DW ?
  28.      ESC_CHAR  DB ?
  29.  
  30. Later, you can load or store these variables:
  31.  
  32.      MOV SI,DATA_PTR    ; load DATA_PTR into SI for use
  33.      LODSW              ; fetch the word pointed to by DATA_PTR
  34.      MOV DATA_PTR,SI    ; store the value incremented by the LODSW
  35.      MOV BL,ESC_CHAR    ; load the byte variable ESC_CHAR
  36.  
  37. Alternatively, you can address specific unnamed memory locations
  38. by enclosing the location value in square brackets; for example,
  39.  
  40.      MOV AL,[02000]     ; load contents of location 02000 into AL
  41.  
  42. Note that A86 discerned from context (loading into AL) that a
  43. BYTE at 02000 was intended.  Sometimes this is impossible, and
  44. you must specify byte or word:
  45.  
  46.      INC B[02000]       ; increment the byte at location 02000
  47.      MOV W[02000],0     ; set the WORD at location 02000 to zero
  48.                                                               6-2
  49.  
  50. INDEXED MEMORY: The 86 supports the use of certain registers as
  51. base pointers and index registers into memory.  BX and BP are the
  52. base registers; SI and DI are the index registers.  You may
  53. combine at most one base register, at most one index register,
  54. and a constant number into a run time pointer that determines the
  55. location of the effective address memory to be used in the
  56. instruction.  These can be given explicitly, by enclosing the
  57. index registers in brackets:
  58.  
  59.      MOV AX,[BX]
  60.      MOV CX,W[SI+17]
  61.      MOV AX,[BX+SI+5]
  62.      MOV AX,[BX][SI]5   ; another way to write the same instr.
  63.  
  64. Or, indexing can be accomplished by declaring variables in a
  65. based structure (see the STRUC directive in Chapter 9):
  66.  
  67.      STRUC [BP]        ; NOTE: based structures are unique to A86!
  68.        BP_SAVE   DW ?  ; BP_SAVE is a word at [BP]
  69.        RET_ADDR  DW ?  ; RET_ADDR is a word at [BP+2]
  70.        PARM1     DW ?  ; PARM1 is a word at [BP+4]
  71.        PARM2     DW ?  ; PARM2 is a word at [BP+6]
  72.      ENDS
  73.      INC PARM1         ; equivalent to INC W[BP+4]
  74.  
  75. Finally, indexing can be done by mixing explicit components with
  76. declared ones:
  77.  
  78.      TABLE    DB  4,2,1,3,5
  79.      MOV AL,TABLE[BX]        ; load byte number BX of TABLE
  80.  
  81.  
  82. Segmentation and Effective Addresses
  83.  
  84. The 86 family has four segment registers, CS, DS, ES, and SS,
  85. used to address memory.  Each segment register points to 64K
  86. bytes of memory within the 1-megabyte memory space of the 86.
  87. (The start of the 64K is calculated by multiplying the segment
  88. register value by 16; i.e., by shifting the value left by one hex
  89. digit.)  If your program's code, data and stack areas can all fit
  90. in the same 64K bytes, you can leave all the segment registers
  91. set to the same value.  In that case, you won't have to think
  92. about segment registers--no matter which one is used to address
  93. memory, you'll still get the same 64K.  If your program needs
  94. more than 64K, you must point one or more segment registers to
  95. other parts of the memory space.  In this case, you must take
  96. care that your memory references use the segment registers you
  97. intended.
  98.  
  99. Each effective address memory access has a default segment
  100. register, to be used if you do not explicitly specify which
  101. segment register you wish.  For most effective addresses, the
  102. default segment register is DS.  The exceptions are those
  103. effective addresses that use the BP register for indexing.  All
  104. BP-indexed memory references have a default of SS.  (This is
  105. because BP is intended to be used for addressing local variables,
  106. stored on the stack.)
  107.                                                               6-3
  108.  
  109. If you wish your memory access to use a different segment
  110. register, you provide a segment override byte before the
  111. instruction containing the effective address operand.  In the A86
  112. language, you code the override by giving the name of the segment
  113. register you wish before the instruction mnemonic.  For example,
  114. suppose you want to load the AL register with the memory byte
  115. pointed to by BX.  If you code MOV AL,[BX], the DS register will
  116. be used to determine which 64K segment BX is pointing to.  If you
  117. want the byte to come from the CS-segment instead, you code CS
  118. MOV AL,[BX].  Be aware that the segment override byte has effect
  119. only upon the single instruction that follows it.  If you have a
  120. sequence of instructions requiring overrides, you must give an
  121. override byte before every instruction in the sequence.  (In that
  122. case, you may wish to consider changing the value of the default
  123. segment register for the duration of the sequence.)
  124.  
  125. NOTE: This method for providing segment overrides is unique to
  126. the A86 assembler!  The assemblers provided by Intel and IBM (MS-
  127. DOS) attempt to figure out segment allocation for you, and plug
  128. in segment override bytes "behind your back".  In order to do
  129. this, those assemblers require you to inform them which variables
  130. and structures are pointed to by which segment registers.  That
  131. is what the ASSUME directive in those assemblers is all about.  I
  132. wrote Intel's first 86 assembler, ASM86, so I have been watching
  133. the situation since day one.  Over the years, I have concluded
  134. that the ASSUME mechanism creates far, far more confusion that it
  135. solves.  So I scrapped it; and the result is an assembler with
  136. far less red tape.  But if your program needs more than 64K, you
  137. do have to manage those segment registers yourself; so take care!
  138.  
  139.  
  140. Effective Use of Effective Addresses
  141.  
  142. Remember that all of the common instructions of the 86 family
  143. allow effective addresses as operands.  (The only major functions
  144. that don't are the AL/AX specific ones: multiply, divide, and
  145. input/output).  This means that you don't have to funnel many
  146. through AL or AX just to do something with them.  You can perform
  147. all the common arithmetic, PUSH/POP, and MOVes from any general
  148. register to any general register; from any memory location
  149. (indexed if you like) to any register; and (this is most often
  150. overlooked) from any register TO memory.  The only thing you
  151. can't do in general is memory-to-memory.  Among the more common
  152. operations that inexperienced 86 programmers overlook are:
  153.  
  154.    * setting memory variables to immediate values
  155.  
  156.    * testing memory variables, and comparing them to constants
  157.  
  158.    * preserving memory variables by PUSHing and POPping them
  159.  
  160.    * incrementing and decrementing memory variables
  161.  
  162.    * adding into memory variables
  163.                                                               6-4
  164.  
  165. Encoding of Effective Addresses
  166.  
  167. Unless you are concerned with the nitty-gritty details of 86
  168. instruction encoding, you don't need to read this section.
  169.  
  170. Every instruction with an effective address has an encoded byte,
  171. known as the effective address byte, following the 1-byte opcode
  172. for the instruction. (For obscure reasons, Intel calls this byte
  173. the ModRM byte.)  If the effective address is a memory variable,
  174. or an indexed memory location with a non-zero constant offset,
  175. then the effective address byte will be immediately followed by
  176. the offset amount.  Amounts in the range -128 to +127 are given
  177. by a single signed byte, denoted by "d8" in the table below.
  178. Amounts requiring a 2-byte representation are denoted by "d16" in
  179. the table below.  As with all 16-bit memory quantities in the 86
  180. family, the word is stored with the least significant byte FIRST.
  181.  
  182. The following table of effective address byte values is organized
  183. into 32 rows and 8 columns.  The 32 rows give the possible values
  184. for the effective address operand: 8 registers and 24 memory
  185. indexing modes.  A 25th indexing mode, [BP] with zero
  186. displacement, has been pre-empted by the simple-memory-variable
  187. case.  If you code [BP] with no displacement, you will get
  188. [BP]+d8, with a d8-value of zero.
  189.  
  190. The 8 columns of the table reflect further information given by
  191. the effective address byte.  Usually, this is the identity of the
  192. other (always a register) operand of a 2-operand instruction.
  193. Those instructions are identified by a "/r" following the opcode
  194. byte in the instruction list.  Sometimes, the information given
  195. supplements the opcode byte in identifying the instruction
  196. itself.  Those instructions are identified by a "/" followed by a
  197. digit from 0 through 7.  The digit tells which of the 8 columns
  198. you should use to find the effective address byte.
  199.  
  200. For example, suppose you have a perverse wish to know the precise
  201. bytes encoded by the instruction SUB B[BX+17],100.  This
  202. instruction subtracts an immediate quantity, 100, from an
  203. effective address quantity, B[BX+17].  By consulting the
  204. instruction list, you find the general form SUB eb,ib.  The
  205. opcode bytes given there are 80 /5 ib.  The "/5" denotes an
  206. effective address byte, whose value will be taken from column 5
  207. of the table below.  The offset 17 decimal, which is 11 hex, will
  208. fit in a single "d8" byte, so we take our value from the "[BX] +
  209. d8" row.  The table tells us that the effective address byte is
  210. 6F.  Immediately following the 6F is the offset, 11 hex.
  211. Following that is the ib-value of 100 decimal, which is 64 hex.
  212. So the bytes generated by SUB B[BX+17],100 are 80 6F 11 64.
  213.  
  214.  
  215.                                                               6-5
  216.  
  217. Table of Effective Address byte values
  218.  
  219. s  =     ES   CS   SS   DS
  220. rb =     AL   CL   DL   BL   AH   CH   DH   BH
  221. rw =     AX   CX   DX   BX   SP   BP   SI   DI
  222. digit=    0    1    2    3    4    5    6    7
  223.                                                   Effective
  224. EA byte                                           address:
  225. values:  00   08   10   18   20   28   30   38    [BX + SI]
  226.          01   09   11   19   21   29   31   39    [BX + DI]
  227.          02   0A   12   1A   22   2A   32   3A    [BP + SI]
  228.          03   0B   13   1B   23   2B   33   3B    [BP + DI]
  229.  
  230.          04   0C   14   1C   24   2C   34   3C    [SI]
  231.          05   0D   15   1D   25   2D   35   3D    [DI]
  232.          06   0E   16   1E   26   2E   36   3E    d16 (simple var)
  233.          07   0F   17   1F   27   2F   37   3F    [BX]
  234.  
  235.          40   48   50   58   60   68   70   78    [BX + SI] + d8
  236.          41   49   51   59   61   69   71   79    [BX + DI] + d8
  237.          42   4A   52   5A   62   6A   72   7A    [BP + SI] + d8
  238.          43   4B   53   5B   63   6B   73   7B    [BP + DI] + d8
  239.  
  240.          44   4C   54   5C   64   6C   74   7C    [SI] + d8
  241.          45   4D   55   5D   65   6D   75   7D    [DI] + d8
  242.          46   4E   56   5E   66   6E   76   7E    [BP] + d8
  243.          47   4F   57   5F   67   6F   77   7F    [BX] + d8
  244.  
  245.          80   88   90   98   A0   A8   B0   B8    [BX + SI] + d16
  246.          81   89   91   99   A1   A9   B1   B9    [BX + DI] + d16
  247.          82   8A   92   9A   A2   AA   B2   BA    [BP + SI] + d16
  248.          83   8B   93   9B   A3   AB   B3   BB    [BP + DI] + d16
  249.  
  250.          84   8C   94   9C   A4   AC   B4   BC    [SI] + d16
  251.          85   8D   95   9D   A5   AD   B5   BD    [DI] + d16
  252.          86   8E   96   9E   A6   AE   B6   BE    [BP] + d16
  253.          87   8F   97   9F   A7   AF   B7   BF    [BX] + d16
  254.  
  255.          C0   C8   D0   D8   E0   E8   F0   F8    ew=AX   eb=AL
  256.          C1   C9   D1   D9   E1   E9   F1   F9    ew=CX   eb=CL
  257.          C2   CA   D2   DA   E2   EA   F2   FA    ew=DX   eb=DL
  258.          C3   CB   D3   DB   E3   EB   F3   FB    ew=BX   eb=BL
  259.  
  260.          C4   CC   D4   DC   E4   EC   F4   FC    ew=SP   eb=AH
  261.          C5   CD   D5   DD   E5   ED   F5   FD    ew=BP   eb=CH
  262.          C6   CE   D6   DE   E6   EE   F6   FE    ew=SI   eb=DH
  263.          C7   CF   D7   DF   E7   EF   F7   FF    ew=DI   eb=BH
  264.  
  265. d8 denotes an 8-bit displacement following the EA byte, to be
  266. sign-extended and added to the index.
  267.  
  268. d16 denotes a 16-bit displacement following the EA byte, to be
  269. added to the index.
  270.  
  271. Default segment register is SS for effective addresses containing
  272. a BP index; DS for other memory effective addresses.
  273.  
  274.  
  275.                                                               6-6
  276.  
  277. How to Read the Instruction Set Chart
  278.  
  279. The following chart summarizes the machine instructions you can
  280. program with A86.  In order to use the chart, you need to learn
  281. the meanings of the specifiers (each given by 2 lower case
  282. letters) that follow most of the instruction mnemonics.  Each
  283. specifier indicates the type of operand (register byte, immediate
  284. word, etc.) that follows the mnemonic to produce the given
  285. opcodes.
  286.  
  287.  
  288. "c"  means the operand is a code label, pointing to a part of the
  289.     program to be jumped to or called.  A86 will also accept a
  290.     constant offset in this place (or a constant segment-offset
  291.     pair in the case of "cd").  "cb" is a label within about 128
  292.     bytes (in either direction) of the current location.  "cw" is
  293.     a label within the same code segment as this program; "cd" is
  294.     a pair of constants separated by a colon-- the segment value
  295.     to the left of the colon, and the offset to the right.  Note
  296.     that in both the cb and cw cases, the object code generated
  297.     is the offset from the location following the current
  298.     instruction, not the absolute location of the label operand.
  299.     In some assemblers (most notably for the Z-80 processor) you
  300.     have to code this offset explicitly by putting "$-" before
  301.     every relative jump operand in your source code.  You do NOT
  302.     need to, and should not do so with A86.
  303.  
  304. "e"  means the operand is an Effective Address.  The concept of
  305.     an Effective Address is central to the 86 machine
  306.     architecture, and thus to 86 assembly language programming.
  307.     It is described in detail at the start of Chapter 8.  We
  308.     summarize here by saying that an Effective Address is either
  309.     a general purpose register, a memory variable, or an indexed
  310.     memory quantity.  For example, the instruction "ADD rb,eb"
  311.     includes the instructions: ADD AL,BL, and ADD CH,BYTEVAR, and
  312.     ADD DL,B[BX+17].
  313.  
  314. "i"  means the operand is an immediate constant, provided as part
  315.     of the instruction itself.  "ib" is a byte-sized constant;
  316.     "iw" is a constant occupying a full 16-bit word.  The operand
  317.     can also be a label, defined with a colon.  In that case, the
  318.     immediate constant which is the location of the label is
  319.     used.  Examples:  "MOV rw,iw" includes the instructions: MOV
  320.     AX,17, or MOV SI,VAR_ARRAY, where "VAR_ARRAY:" appears
  321.     somewhere in the program, defined with a colon.  NOTE that if
  322.     VAR_ARRAY were defined without a colon, e.g., "VAR_ARRAY DW
  323.     1,2,3", then "MOV SI,VAR_ARRAY" would be a "MOV rw,ew" NOT a
  324.     "MOV rw,iw".  The MOV would move the contents of memory at
  325.     VAR_ARRAY (in this case 1) into SI, instead of the location
  326.     of the memory. To load the location, you can code "MOV
  327.     SI,OFFSET VAR_ARRAY".
  328.  
  329. "m"  means a memory variable or an indexed memory quantity; i.e.,
  330.     any Effective Address EXCEPT a register.
  331.  
  332. "r"  means the operand is a general purpose register.  The 8 "rb"
  333.     registers are AL,BL,CL,DL,AH,BH,CH,DH; the 8 "rw" registers
  334.     are AX,BX,CX,DX,SI,DI,BP,SP.
  335.                                                               6-7
  336.  
  337. WARNING: Instruction forms marked with "*" by the mnemonic are
  338. part of the extended 186/286/NEC instruction set. Instructions
  339. marked with "#" are unique to the NEC processors.  These
  340. instructions will NOT work on the 8088 of the IBM-PC; nor will
  341. they work on the 8086; nor will the NEC instructions work on the
  342. 186 or 286. If you wish your programs to run on all PC's, do not
  343. use these instructions!
  344.  
  345.